package com.luckynote.common.base.util;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;

/**
 * <pre>
 * *********************************************
 * Copyright LUCKY-NOTE.
 * All rights reserved.
 * ****************************************************
 *  Version       Date         Author            Desc
 *    v1.0       2019/6/29      bingo           空值检查工具类
 * ****************************************************
 * </pre>
 */
public class NullCheckUtil {

    /**
     * 根据对象及属性名字符串/数组/集合 判空
     *
     * @param beCheckObj     需判空的对象
     * @param attributeNames 字符串数组，数组元素为需判空的属性名。为空时，校验所有属性。
     * @return 值或元素为空的对象或属性，用","分隔
     */
    public static String nullCheck(Object beCheckObj, String[] attributeNames) {
        StringBuilder nullAttributeNames = new StringBuilder();
        try {
            if (beCheckObj == null)
                return "null";
            Class<?> clazz = beCheckObj.getClass();
            if (attributeNames == null || attributeNames.length == 0) {
                Field[] fields = clazz.getDeclaredFields();
                attributeNames = new String[fields.length];
                for (int i = 0; i < fields.length; i++) {
                    attributeNames[i] = fields[i].getName();
                }
            }
            for (String attributeName : attributeNames) {
                PropertyDescriptor descriptor = new PropertyDescriptor(attributeName, clazz);
                Method readMethod = descriptor.getReadMethod();
                if (readMethod == null)
                    continue;
                Object obj = readMethod.invoke(beCheckObj);
                if (null == obj
                        || (obj instanceof String && StringUtil.isEmptyString((String) obj))
                        || (obj instanceof Collection && ((Collection) obj).isEmpty())
                        || (obj.getClass().isArray() && Array.getLength(obj) <= 0)
                ) {
                    nullAttributeNames.append(",").append(attributeName);
                }
            }
        } catch (IntrospectionException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        return nullAttributeNames.toString();
    }

    /**
     * 根据对象判空所有属性
     *
     * @param beCheckObj 需判空的对象
     * @return 值或元素为空的对象或属性，用","分隔
     */
    public static String nullCheck(Object beCheckObj) {
        return nullCheck(beCheckObj, null);
    }
}
